/**
 * <p>Title: Physics.java</p>
 * <p>Description: CS 343 Final Project. This class is dealing with the physics of the hero</p>
 * @author Tim Olmstead, Brady Fetting, Erik Brown, Thales Kirk
 * @email timothy.olmstead@my.uwrf.edu, brady.fetting@my.uwrf.edu, 
 * 			erik.brown@my.uwrf.edu, thales.kirk@my.uwrf.edu
 * @date November 15, 2013
 */

package Components;

import java.awt.Point;
import java.awt.Polygon;
import java.util.ConcurrentModificationException;
import GameState.Game;
import Obstacles.Obstacle;

public class Physics implements Runnable {

	private boolean endThread = false;
	private long lastPhysicsicsUpdate;
	private long waitTime = 16;
	private boolean suspended = false;
	private long gameSpeedIncreaseTime = 38000;
	private long lastSpeedUpdate;

	/**
	 * @description this function moves the players and obstacles in association
	 *              to the background and dependent on the games speed
	 * @description The collision detection method is called here.
	 */
	public void compute() {

		while (true) {
			if (!suspended) {

				if (lastPhysicsicsUpdate < System.currentTimeMillis()
						- waitTime) { // check
										// for
										// 60fps
										// updates

					// move player
					Game.player.move();

					// move all obstavles
					Game.getObstacleContainer().moveObstacles();

					Game.getMobcontainer().move();

					// move background
					Game.getMoveableBackground().move(Game.getGameSpeed());

					try {
						// COLISION DETECTION!!!!!!!!!!!!!
						for (Obstacle x : Game.getObstacleContainer().getObs()) {
							if (polygonIntersectsPolygon(
									Game.player.getPolygon(), x.getPolygon())) {
								Game.player.die();

							}
						}
					} catch (ConcurrentModificationException a) {
						System.err
								.println("Exception caught in physics thread - ConcurrentModificationException");
					}

					lastPhysicsicsUpdate = System.currentTimeMillis();
				}// end of time check

				// increase game speed if time is ready
				if (lastSpeedUpdate < System.currentTimeMillis()
						- gameSpeedIncreaseTime) {
					Game.setGameSpeed(Game.getGameSpeed() + 1);
					System.out.println("GAME SPEED INCREASE!!!!!!!");
					lastSpeedUpdate = System.currentTimeMillis();
				}
			}
			try {
				Thread.sleep(1);// to keep from eating all of the processing.
								// hold up for a millisec
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			if (endThread) {
				break;
			}
		}// end of loop

	}// end of compute

	/**
	 * @param none
	 * @description ends the thread
	 */
	public void endThread() {
		// speedOfGame.pause();
		endThread = true;
	}

	/**
	 * @param none
	 * @description enables the thread
	 */
	public void enableThread() {
		endThread = false;
	}

	/**
	 * @param none
	 * @description suspends the thread
	 */
	public void suspendThread() {
		suspended = true;
	}

	/**
	 * @param none
	 * @description unsuspends the thread
	 */
	public void unsuspendThread() {
		suspended = false;
	}

	/**
	 * @description checks the update, creates a speedOfGame object to speed up
	 *              the game as time progresses,
	 * @description-Continued:: and starts the compute method while thread is
	 *                          running
	 */
	public void run() {
		lastPhysicsicsUpdate = System.currentTimeMillis();
		lastSpeedUpdate = lastPhysicsicsUpdate;
		compute();
	}

	/**
	 * * Determines if the two polygons supplied intersect each other, by
	 * checking if either polygon has points which are contained in the other. *
	 * (It doesn't detect body-only intersections, but is sufficient in most
	 * cases.)
	 * 
	 * - All about Polygons :)
	 * http://docs.oracle.com/javase/6/docs/api/java/awt/Polygon.html - Source
	 * of this function
	 * http://wikicode.wikidot.com/check-for-polygon-polygon-intersection
	 */
	public static boolean polygonIntersectsPolygon(Polygon p1, Polygon p2) {
		Point p;
		for (int i = 0; i < p2.npoints; i++) {
			p = new Point(p2.xpoints[i], p2.ypoints[i]);
			if (p1.contains(p))
				return true;
		}
		for (int i = 0; i < p1.npoints; i++) {
			p = new Point(p1.xpoints[i], p1.ypoints[i]);
			if (p2.contains(p))
				return true;
		}
		return false;
	}

}
